﻿using System;

namespace DotNetCommon;

/// <summary>
/// <list type="bullet">
/// <item>UnitConverter.Humanize(1024.23d): "1 KB"</item>
/// <item>UnitConverter.MoneyToUpper(12.323): "壹拾贰圆叁角贰分"</item>
/// </list>
/// </summary>
public static class UnitConverter
{
    #region KB/MB/GB 转换
    private const double KiloBytes = 1024;
    private const double MegaBytes = KiloBytes * KiloBytes;
    private const double GigaBytes = KiloBytes * MegaBytes;

    /// <summary>
    /// 将字节大小的值转成人类易读的字符串
    /// </summary>
    public static string Humanize(double bytes)
    {
        var abs = Math.Abs(bytes);
        if (abs == 0) return $"0 B";

        if (abs >= GigaBytes)
        {
            return $"{bytes / GigaBytes:#,#.##} GB";
        }

        if (abs >= MegaBytes)
        {
            return $"{bytes / MegaBytes:#,#.##} MB";
        }

        if (abs >= KiloBytes)
        {
            return $"{bytes / KiloBytes:#,#.##} KB";
        }

        return $"{bytes:#,#} B";
    }

    /// <summary>
    /// 将 <c>B</c> 转成 <c>MB</c>
    /// </summary>
    public static double BytesToMegaBytes(this double bytes) => bytes / MegaBytes;

    /// <summary>
    /// 将 <c>B</c> 转成 <c>GB</c>
    /// </summary>
    public static double BytesToGigaBytes(this double bytes) => bytes / MegaBytes / KiloBytes;

    /// <summary>
    /// 将 <c>KB</c> 转成 <c>MB</c>
    /// </summary>
    public static double KiloBytesToMegaBytes(this double kiloBytes) => kiloBytes / KiloBytes;

    /// <summary>
    /// 将 <c>MB</c> 转成 <c>GB</c>
    /// </summary>
    public static double MegaBytesToGigaBytes(this double megaBytes) => megaBytes / KiloBytes;

    /// <summary>
    /// 将 <c>MB</c> 转成 <c>TB</c>
    /// </summary>
    public static double MegaBytesToTeraBytes(this double megaBytes) => megaBytes / MegaBytes;

    /// <summary>
    /// 将 <c>GB</c> 转成 <c>MB</c>
    /// </summary>
    public static double GigaBytesToMegaBytes(this double gigaBytes) => gigaBytes * KiloBytes;

    /// <summary>
    /// 将 <c>GB</c> 转成 <c>TB</c>
    /// </summary>
    public static double GigaBytesToTeraBytes(this double gigaBytes) => gigaBytes / KiloBytes;

    /// <summary>
    /// 将 <c>TB</c> 转成 <c>MB</c>
    /// </summary>
    public static double TeraBytesToMegaBytes(this double teraBytes) => teraBytes * MegaBytes;

    /// <summary>
    /// 将 <c>TB</c> 转成 <c>GB</c>
    /// </summary>
    public static double TeraBytesToGigaBytes(this double teraBytes) => teraBytes * KiloBytes;
    #endregion

    #region 转金额为大写
    /// <summary>
    /// 将金额转为大写(保留两位小数（123.489→123.49　　123.4→123.4）、最大9999万亿), 示例:
    /// <code>
    /// UnitConverter.MoneyToUpper(12.32m);
    /// //输出: 壹拾贰圆叁角贰分
    /// </code>
    /// </summary>
    public static string MoneyToUpper(decimal amount) => MoneyToUpper(amount.ToString());

    /// <summary>
    /// 将金额转为大写(保留两位小数（123.489→123.49　　123.4→123.4）、最大9999万亿), 示例:
    /// <code>
    /// UnitConverter.MoneyToUpper(12.32);
    /// //输出: 壹拾贰圆叁角贰分
    /// </code>
    /// </summary>
    public static string MoneyToUpper(double amount) => MoneyToUpper(amount.ToString());

    /// <summary>
    /// 将金额转为大写(保留两位小数（123.489→123.49　　123.4→123.4）、最大9999万亿), 示例:
    /// <code>
    /// UnitConverter.MoneyToUpper(12.32.ToString());
    /// //输出: 壹拾贰圆叁角贰分
    /// </code>
    /// </summary>
    public static string MoneyToUpper(string strAmount)
    {
        if (string.IsNullOrWhiteSpace(strAmount)) return string.Empty;
        string functionReturnValue = null;
        bool IsNegative = false; // 是否是负数
        if (strAmount.Trim().Substring(0, 1) == "-")
        {
            // 是负数则先转为正数
            strAmount = strAmount.Trim().Remove(0, 1);
            IsNegative = true;
        }
        string strLower = null;
        string strUpart = null;
        string strUpper = null;
        int iTemp = 0;
        // 保留两位小数 123.489→123.49　　123.4→123.4
        strAmount = Math.Round(double.Parse(strAmount), 2).ToString();
        if (strAmount.IndexOf('.') > 0)
        {
            if (strAmount.IndexOf('.') == strAmount.Length - 2)
            {
                strAmount += "0";
            }
        }
        else
        {
            strAmount += ".00";
        }
        strLower = strAmount;
        iTemp = 1;
        strUpper = "";
        while (iTemp <= strLower.Length)
        {
            switch (strLower.Substring(strLower.Length - iTemp, 1))
            {
                case ".":
                    strUpart = "圆";
                    break;
                case "0":
                    strUpart = "零";
                    break;
                case "1":
                    strUpart = "壹";
                    break;
                case "2":
                    strUpart = "贰";
                    break;
                case "3":
                    strUpart = "叁";
                    break;
                case "4":
                    strUpart = "肆";
                    break;
                case "5":
                    strUpart = "伍";
                    break;
                case "6":
                    strUpart = "陆";
                    break;
                case "7":
                    strUpart = "柒";
                    break;
                case "8":
                    strUpart = "捌";
                    break;
                case "9":
                    strUpart = "玖";
                    break;
            }

            switch (iTemp)
            {
                case 1:
                    strUpart += "分";
                    break;
                case 2:
                    strUpart += "角";
                    break;
                case 3:
                    strUpart += "";
                    break;
                case 4:
                    strUpart += "";
                    break;
                case 5:
                    strUpart += "拾";
                    break;
                case 6:
                    strUpart += "佰";
                    break;
                case 7:
                    strUpart += "仟";
                    break;
                case 8:
                    strUpart += "万";
                    break;
                case 9:
                    strUpart += "拾";
                    break;
                case 10:
                    strUpart += "佰";
                    break;
                case 11:
                    strUpart += "仟";
                    break;
                case 12:
                    strUpart += "亿";
                    break;
                case 13:
                    strUpart += "拾";
                    break;
                case 14:
                    strUpart += "佰";
                    break;
                case 15:
                    strUpart += "仟";
                    break;
                case 16:
                    strUpart += "万";
                    break;
                case 17:
                    strUpart += "拾";
                    break;
                case 18:
                    strUpart += "佰";
                    break;
                case 19:
                    strUpart += "仟";
                    break;
                default:
                    strUpart += "";
                    break;
            }

            strUpper = strUpart + strUpper;
            iTemp = iTemp + 1;
        }

        strUpper = strUpper.Replace("零拾", "零");
        strUpper = strUpper.Replace("零佰", "零");
        strUpper = strUpper.Replace("零仟", "零");
        strUpper = strUpper.Replace("零零零", "零");
        strUpper = strUpper.Replace("零零", "零");
        strUpper = strUpper.Replace("零角零分", "整");
        strUpper = strUpper.Replace("零分", "");
        strUpper = strUpper.Replace("零角", "");
        strUpper = strUpper.Replace("零亿零万零圆", "亿圆");
        strUpper = strUpper.Replace("亿零万零圆", "亿圆");
        strUpper = strUpper.Replace("零亿零万", "亿");
        strUpper = strUpper.Replace("零万零圆", "万圆");
        strUpper = strUpper.Replace("零亿", "亿");
        strUpper = strUpper.Replace("零万", "万");
        strUpper = strUpper.Replace("零圆", "圆");
        strUpper = strUpper.Replace("零零", "零");

        // 对壹圆以下的金额的处理
        if (strUpper[..1] == "圆")
        {
            strUpper = strUpper[1..];
        }
        if (strUpper[..1] == "零")
        {
            strUpper = strUpper[1..];
        }
        if (strUpper[..1] == "角")
        {
            strUpper = strUpper.Substring(1, strUpper.Length - 1);
        }
        if (strUpper[..1] == "分")
        {
            strUpper = strUpper.Substring(1, strUpper.Length - 1);
        }
        if (strUpper[..1] == "整")
        {
            strUpper = "零圆整";
        }
        functionReturnValue = strUpper;

        if (IsNegative == true)
        {
            return "负" + functionReturnValue;
        }
        else
        {
            return functionReturnValue;
        }
    }
    #endregion
}